﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Display;
using PlanningGIS.Util.Convertor;

namespace PlanningGIS.ArcGIS
{
    /// <summary>
    /// 打印操作类
    /// </summary>
    public class PrintHelper
    {
        /// <summary>
        /// 获取布局上的点
        /// </summary>
        /// <param name="pMapPoint"></param>
        /// <param name="pPrj"></param>
        /// <param name="pMapFrame"></param>
        /// <returns></returns>
        public static IPoint GetPaperPoint(IPoint pMapPoint, IProjectedCoordinateSystem pPrj, IMapFrame pMapFrame)
        {
            IActiveView pAv = (IActiveView)pMapFrame.Map;
            IEnvelope pMapEnvelope = pAv.Extent;
            IElement pElement = (IElement)pMapFrame;
            IEnvelope pPaperEnvelope = pElement.Geometry.Envelope;
            IPoint pMapPoint1 = pMapEnvelope.LowerLeft;
            IPoint pMapPoint2 = pMapEnvelope.UpperRight;
            IPoint pPaperPoint1 = pPaperEnvelope.LowerLeft;
            IPoint pPaperPoint2 = pPaperEnvelope.UpperRight;

            double dblX = (pPaperPoint1.X - pPaperPoint2.X) * (pMapPoint.X - pMapPoint1.X) / (pMapPoint1.X - pMapPoint2.X) + pPaperPoint1.X;
            double dblY = (pPaperPoint1.Y - pPaperPoint2.Y) * (pMapPoint.Y - pMapPoint1.Y) / (pMapPoint1.Y - pMapPoint2.Y) + pPaperPoint1.Y;

            IPoint pPoint = new Point();
            pPoint.PutCoords(dblX, dblY);

            return pPoint;
        }

        /// <summary>
        /// 获取布局上的点
        /// </summary>
        /// <param name="pMapPoint"></param>
        /// <param name="pMapPoint1"></param>
        /// <param name="pMapPoint2"></param>
        /// <param name="pPaperPoint1"></param>
        /// <param name="pPaperPoint2"></param>
        /// <returns></returns>
        public static IPoint GetPaperPoint(IPoint pMapPoint, IPoint pMapPoint1, IPoint pMapPoint2, IPoint pPaperPoint1, IPoint pPaperPoint2)
        {
            double dblX = (pPaperPoint1.X - pPaperPoint2.X) * (pMapPoint.X - pMapPoint1.X) / (pMapPoint1.X - pMapPoint2.X) + pPaperPoint1.X;
            double dblY = (pPaperPoint1.Y - pPaperPoint2.Y) * (pMapPoint.Y - pMapPoint1.Y) / (pMapPoint1.Y - pMapPoint2.Y) + pPaperPoint1.Y;

            IPoint pPoint = new Point();
            pPoint.PutCoords(dblX, dblY);

            return pPoint;
        }

        /// <summary>
        /// 获取布局上的点
        /// </summary>
        /// <param name="dblX"></param>
        /// <param name="dblY"></param>
        /// <param name="pMapFrame"></param>
        /// <param name="pPrj"></param>
        /// <returns></returns>
        public static double GetPaperXY(double dblX, double dblY, IMapFrame pMapFrame, IProjectedCoordinateSystem pPrj)
        {
            IActiveView pAv = (IActiveView)pMapFrame.Map;
            IEnvelope pMapEnvelope = pAv.Extent;
            IElement pElement = (IElement)pMapFrame;
            IEnvelope pPaperEnvelope = pElement.Geometry.Envelope;
            IPoint pMapPoint1 = pMapEnvelope.LowerLeft;
            IPoint pMapPoint2 = pMapEnvelope.UpperRight;
            IPoint pPaperPoint1 = pPaperEnvelope.LowerLeft;
            IPoint pPaperPoint2 = pPaperEnvelope.UpperRight;

            if (dblY == 0)
            {
                return (pPaperPoint1.X - pPaperPoint2.X) * (dblX - pMapPoint1.X) / (pMapPoint1.X - pMapPoint2.X) + pPaperPoint1.X;
            }
            else if (dblX == 0)
            {
                return (pPaperPoint1.Y - pPaperPoint2.Y) * (dblY - pMapPoint1.Y) / (pMapPoint1.Y - pMapPoint2.Y) + pPaperPoint1.Y;
            }
            else
            {
                return 0;
            }
        }

        #region 与打印相关的函数
        
        /// <summary>
        /// 根据自定义范围在PageLayout上生成地图框
        /// add by wzy
        /// </summary>
        /// <param name="MainMapControl">当前地图控件</param>
        /// <param name="axPageLayoutFrame">当前制图控件</param>
        /// <param name="pEnv">自定义打印范围</param>
        /// <param name="dScale">制图比例尺</param>
        /// <param name="iPageID">页面大小</param>
        /// <param name="iOri">页面方向</param>
        public static void DrawCustomMapFrame(IMapControl3 MainMapControl, IPageLayoutControl2 axPageLayoutFrame, IEnvelope pEnv, double dScale, int iPageID, short iOri)
        {
            //清空原有地图框
            axPageLayoutFrame.GraphicsContainer.DeleteAllElements();

            //初始化地图框
            IElement pMapElement = (IElement)axPageLayoutFrame.FindElementByName("Layers", 1);
            IMapFrame pMapFrame;
            if (pMapElement != null)
            {
                pMapFrame = (IMapFrame)pMapElement;
                ISymbolBorder pSymbolBorder = (ISymbolBorder)pMapFrame.Border;
                ILineSymbol pLineSymbol = pSymbolBorder.LineSymbol;
                pLineSymbol.Width = 0.1 * 2.8346;
                pSymbolBorder.LineSymbol = pLineSymbol;
                pMapFrame.Border = pSymbolBorder;
            }
            else
            {
                return;
            }

            Envelope MapEnv = new Envelope();

            //同步数据内容
            SynchroPageMap(MainMapControl, axPageLayoutFrame);

            //设置页面
            axPageLayoutFrame.Page.FormID = (esriPageFormID)iPageID;

            IPage pPage = axPageLayoutFrame.Page;
            double dPageW = 0;
            double dPageH = 0;
            pPage.QuerySize(out dPageW, out dPageH);

            axPageLayoutFrame.Page.Orientation = iOri;

            //计算地图框位置
            double dPBP = 0.05; // 页边距与页宽的比值
            double dPB = dPageW * dPBP;

            MapEnv.XMin = dPB;
            MapEnv.YMin = dPB;
            MapEnv.XMax = dPB + pEnv.Width / dScale * 100;
            MapEnv.YMax = dPB + pEnv.Height / dScale * 100;

            //添加地图框要素
            pMapElement = (IElement)pMapFrame;
            IGeometry pGeoExt = (IGeometry)MapEnv;
            pMapElement.Geometry = pGeoExt;

            IGraphicsContainer pGraphicsContainer = (IGraphicsContainer)axPageLayoutFrame.PageLayout;
            pGraphicsContainer.AddElement(pMapElement, 2);
            IActiveView pActView = axPageLayoutFrame.ActiveView;
        }

        /// <summary>
        /// 同步地图控件与布局控件的地图
        /// </summary>
        /// <param name="mapControl">数据视图控件</param>
        /// <param name="pageLayout">打印视图控件</param>
        public static void SynchroPageMap(IMapControl3 mapControl, IPageLayoutControl2 pageLayout)
        {
            if (mapControl == null || pageLayout == null) return;
            IObjectCopy pObjectCopy = new ObjectCopy();
            object pToCopyMap = mapControl.Map;
            object pCopiedMap = pObjectCopy.Copy(pToCopyMap);
            object pToOverwriteMap = pageLayout.ActiveView.FocusMap;
            pObjectCopy.Overwrite(pToCopyMap, ref pToOverwriteMap);
        }

        #endregion

    }
}